CSS 盒模型
经典图解
如上图所述,每个 HTML 元素,都像一个盒子,而这个盒子,有content
(内容),padding
(填充缝隙),border
(边界/外壳),margin
(边缘空白)。
content
:可以理解为盒子里装的内容物padding
:可以理解为盒子的外壳和内容之间的缝隙(或者是填充物),就像快递盒子里面可能会填上那种充气的保护垫border
:可以理解为盒子的外壳margin
:可以理解为盒子与盒子间的空隙
相关属性
width
元素宽度
width:<length>|<percentage>|auto|inherit</span>
解释:
- 该属性,很明显,是用来设置元素宽度的,但是具体设置的是
content
部分的宽度,还是border
包含的部分的宽度,要视情况而定,本篇后面会讲 - 一般对于
inline
(行级)元素设置宽度是没有意义的,只给inline-block
,block
或者其他某些类型的元素设置宽度 - 默认值是
auto
,没有继承性,除非设置了inherit
- 引申出
min-width
,max-width
属性,是给元素设置最小宽度和最大宽度的
height
元素高度
height:<length>|<percentage>|auto|inherit</span>
解释:
- 和
width
一致
padding
填充宽度
padding:[<length>|<percentage>]{1, 4}|inherit</span>
解释:
padding
是设置填充宽度的一个属性。可以设置 1 到 4 个值,分别设置上、右、下、左(顺时针)四个填充宽度,如上图。- 设置为
<percentage>
时,百分比数值是相对父元素 - 也可以分开设置
padding
:padding-top
,padding-right
,padding-bottom
,padding-left
。 - 举例说明:
- 写一个值的情况:
padding:20px;
,说明四个方向的padding
都是同一个值,也就是 20px - 写两个值的情况:
padding:20px 10px;
,其实等于padding:20px 10px 20px 10px;
,也就是说,如果上和下的padding
相等,那么只要设置一个就够了,左右也是一样。 - 写三个值的情况:
padding:20px 10px 5px;
,其实等于padding:20px 10px 5px 10px
,事实上写三个就只指定了上,右和下的宽度,剩余的左宽度应该等于右边的宽度。
- 写一个值的情况:
- 总结一下规则:
- 对面相等,后者省略
- 四面相等,只写一个
- 其实类似
padding
这样,要对四个方向设值的属性,一般都可以像padding
的规则进行设置。 padding
的颜色和content
的颜色一致,都是background-color
margin
外边距宽度
margin:[<length>|<percentage>|auto]{1, 4}|inherit</span>
解释:
margin
的书写方式基本上和padding
是一样的,但是还是有一些区别的。margin
默认为 0,但是可能浏览器的默认样式表会给某些标签设置初始margin
值,比如 IE6、IE7 的 body 标签,默认的样式应该是:display:block;margin:15px 10px;zoom:1;
(不是很确定),而没有预设 padding 值,chrome/firefox 也只是设置了margin:8px;
没有预设 padding- 上下毗邻的两个元素的
margin-top
和margin-bottom
会合并,取两者之间的较大值,看下面这个例子,两个元素间距仅为 30px,而不是 30px+10px:1
2<div style="height:30px;width:100px;margin:30px 10px;background-color:lightseagreen;"></div>
<div style="height:30px;width:100px;margin:10px 10px;background-color:lightseagreen;"></div> - 父元素的上下
margin
分别会和第一个子元素的margin-top
以及最后一个子元素的margin-bottom
进行合并。1
2
3
4<div style="width: 100px; margin: 40px auto; background-color: lightblue;">
<div style="height:30px;width:100px;margin:30px 0;background-color:lightseagreen;"></div>
<div style="height:30px;width:100px;margin:10px 0;background-color:lightseagreen;"></div>
</div>
但值得注意的是,上面这种情况的触发条件是比较苛刻的。只有在父元素没有设置border
的时候才会合并。因为子元素的所有内容(包括margin
)是要完全包含在父元素的border
里面的。假设,我在上面这种情况中,给父元素添加border
,就会变成下面这种情况:
border
边框
border:[<border-width>||<border-style>||<border-color>]|inherit</span> > border-width:[<length>|thin|medium|thick]{1,4}|inherit</span> > border-style:[solid|dashed|dotted|…]{1,4}|inherit</span> > border-color:[<color>|transparent]{1,4}|inherit</span> > border-radius:[<length>|<percentage>]{1,4} [/[<length>|<percentage>]{1,4}]
解释:
- 上面的属性,都可以写成
border-direction-xxx
的形式,如border-bottom-color
。 border-style
最常用的三种就是:solid
(实线),dashed
(虚线),dotted
(点线)- 重点讲一下
border-radius
:
- 事实上,每个角都是一个椭圆,而椭圆都会有两个属性,就是 x 轴长度和 y 轴长度,如图所示。 - 所以设置全部四个角,需要 8 个值来表示,前四个,分别表示 1,2,3,4 个角的 X 轴方向半径,而后四个,则需要在前面加上/
以示区别。比如上图中的圆角矩形,可以写成border-radius: 10px 15px 5px 5px /10px 5px 5px 15px
。 -border-radius
也满足对面相同,后者省略;四面相等,只写一个的规则,也就是,如果 1 号角和 3 号角如果一样,则只要写 1 号角的就行了。 -border-radius
还满足x,y 一致,后者省略的规则,也就是说如果 x 方向半径和 y 方向半径一致的话,y 方向就可以不写 - 对border-radius
设置百分比的值时,是相对本元素的width
和height
而言的。也就是说,如果对一个正方形元素,设置border-radius:50%
就可以变成圆形,如下:
outline
轮廓
outline:[<outline-width>||<outline-style>||<outline-color>]|inherit</span>
outline-width:[<length>|thin|medium|thick]|inherit</span> > outline-style:[solid|dashed|dotted|…]|inherit</span> > outline-color:<color>|inherit</span>
解释:
outline
是在border
外面的一圈,不占据空间的轮廓。基本上和border
的属性一致。- 下面这个例子,你会发现两个
div
块之间,outline
会互相覆盖,这说明outline
并不占据空间。
1 | div { |
overflow
溢出
overflow:visible|hidden|scroll|auto
解释:
overflow
是用来设置如果子元素超过父元素的溢出规则。visible
表示可见;hidden
表示隐藏;scroll
表示固定显示滚动条;auto
表示根据内容多少来选择显示或不显示滚动条;- 效果对比:
overflow: visible; overflow: visible; overflow: visible; overflow: visible; overflow: visible; Jackie Anxis
overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; Jackie Anxis
overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; Jackie Anxis
- 也可以利用
overflow-x
,overflow-y
分别设置 X 和 Y 方向的溢出处理
box-sizing
选择宽度设置
box-sizing:content-box|border-box|inherit</span>
解释:
box-sizing
是用来指定,width
和height
指定的究竟是content
内容的宽度还是border
包含的宽度。- 默认是
content-box
,表示 CSS 样式中,width
和height
指定的是content
内容的宽度,也就是说,width: 100px;padding:10px;
这段代码,实际上border
(不包含border
)里面的内容应该宽为 120px - 设置为
border-box
,表示 CSS 样式中,width
和height
指定的是border
(包括border
在内)包含内容的宽度。
-
1 | width: 100px; |
这段代码,实际上,content
部分的宽度只有 60px,而要加上padding
和border
的宽度才达到 100px。
box-shadow
设置阴影
box-shadow:none|<shadow>[,<shadow>]* > <shadow>:inset?&&<length>{2,4}&&<color>
解释:
box-shadow
用来设置一个元素的阴影,默认是none
,可以是多个值,中间用,
隔开,表示多层阴影。inset
表示内阴影- 对于每一层阴影,
length
可以有 2-4 个,分别表示水平偏移(正值表示向右)、垂直偏移(正值表示向下),模糊半径,阴影大小;如下图所示的一段 CSS:
1 | box-shadow: 10px 10px 5px 20px lightblue; |
黑色边框部分,是向下偏移 10px,向右偏移 10px 应该产生的阴影(也就是box-shadow: 10px 10px lightblue;
的情况下应该有的大小),而红色边框比黑色边框总共宽 40px(2 个阴影大小的宽度),而 5px 的模糊半径,是包含在 20px 的阴影大小里面的。
关于盒模型中百分比的问题做一个统一说明
width
&height
对子元素的
width
和height
设置百分比值,无论父元素的box-sizing
如何,都是相对父元素content
部分进行计算的。
1 | /*left div content-box*/ |
- 第一个父元素的
content-box
的宽为200px
;所以子元素的width
/height
应该是基于200px进行计算的。 - 第二个父元素的
content-box
的宽为200px-10px*2=180px
;所以子元素的width
/height
应该是基于180px
进行计算的。
padding
&margin
&border
对子元素的
padding
和margin
设置百分比值,无论父元素的box-sizing
如何,都是相对父元素content
部分的width
进行计算的。
哦,忘了说了。border
是不允许设置百分比值的。可怜的border
。
1 | /*padding-test*/ |
- 父元素的
content-box
的宽为400px-50px*2=300px
;所以子元素的padding
/margin
应该是基于300px
进行计算的。 - 注意:无论上下还是左右的
padding
或者margin
,都是相对父元素的width
而言的,和height
无关。
border-radius
对元素的
border-radius
设置百分比值,x 轴方向的值是相对于元素border-box
的width
计算的,y 轴方向的值是相对于元素border-box
的height
计算的
1 | div { |
以下是左上角部分截图: